import { GaRegExp, ruleInject, ruleInjectable } from "../InjectionRule";
import { blankRemove } from "../methods/blank-remove";
import { MakeListRule } from "../methods/make-list";

type UnaryOperator = "!" | "~" | "-";
type MathOperation = "+" | "-" | "*" | "/" | "^" | "%" | ">" | "<" | "&" | "|" | ">>" | "<<" | ">=" | "<=" | "==" | "!=" | "||" | "&&";
type MathVariable = [UnaryOperator, `${number}` | string | []];
type MathValue = [MathOperation, MathVariable];
export type MathData = [MathVariable | MathData, [MathValue | MathData]];

@ruleInjectable()
export default class calcRule extends GaRegExp {

	@ruleInject() private unaryRule!: GaRegExp;

	@ruleInject() private variableNameRule!: GaRegExp;

	public RuleInit() {
		this.ParseRule([
			this.Supply("CALC"),
			"(", this.unaryRule, "|", "\\(", blankRemove, this, "\\)", ")",
			blankRemove,

			"(", "(-",
			"(-", this.Supply("CALC_CALC"), "(![\\+\\-\\*\\/\\^%><&\\|]|>>|<<|>=|<=|==|!=|&&|\\|\\|)", blankRemove, "(", this.unaryRule, "|", "\\(", blankRemove, this, "\\)", ")", ")", "|",
			this.Supply("CALC_PARAMS"), "\\(", ...MakeListRule([this]), "\\)", "|",
			this.Supply("CALC_INDEXS"), "\\[", blankRemove, "(", this, ")", blankRemove, "\\]", "|",
			this.Supply("CALC_ATTR"), "\\.", blankRemove, "(", this.variableNameRule, ")", "|",
			this.Supply("CALC_TERNARY"), "\\?", blankRemove, "(", this, ")", blankRemove, ":", blankRemove, "(", this, ")", "|",
			this.Supply("CALC_PP"), "\\+\\+", "|",
			this.Supply("CALC_RR"), "\\-\\-",
			")", blankRemove, ")*",
		]);
	}

}
